﻿using System.Windows;
using ff14bot.Enums;
using ff14bot.Managers;
using System.Linq;
using TreeSharp;
using Magitek.Helpers;
using ff14bot;
using System.Windows.Forms;
using ff14bot.Objects;
using ff14bot.Behavior;
using ff14bot.Helpers;
using System.Windows.Input;

namespace Magitek.Rotations
{
    public class Warrior : Magitek
    {
        public override float PullRange { get { return WindowSettings.WarriorPullRange; } }
        public override ClassJobType[] Class { get { return new ClassJobType[] { ClassJobType.Warrior }; } }
        #region Pulling & Resting
        protected override Composite CreatePull()
        {
            return Combat.CreatePull(4);
        }
        protected override Composite CreateRest()
        {
            return Extensions.DefaultRestBehavior(r => Core.Player.CurrentManaPercent);
        }
        #endregion
        #region Buffs // Mainly used for Grindbot etc...
        protected override Composite CreatePreCombatBuffs()
        {
            return new PrioritySelector(
                Extensions.SummonChocobo()
                );
        }
        protected override Composite CreateCombatBuffs()
        {
            return new PrioritySelector(
                Casting.Cast(r => "Berserk", r => WindowSettings.WarriorUseBerserk, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Holmgang", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseHolmGangHp, r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Thrill of Battle", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseThrillOfBattleHp, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Foresight", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseForesightHp, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Vengeance", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseVengeanceHp, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Second Wind", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseSecondWindHp, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Convalescence", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseConvalescenceHp, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Featherfoot", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseFeatherfootHp, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Awareness", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseAwarenessHp, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Bloodbath", r => Core.Player.CurrentHealthPercent <= WindowSettings.WarriorUseBloodbath, r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Internal Release", r => WindowSettings.WarriorUseInternalRelease && !Core.Player.HasAura("Internal Release"), r => Core.Player, r => 2, r => false),
                Casting.Cast(r => "Infuriate", r => ((Extensions.EnemiesNearTarget(5) >= WindowSettings.WarriorUseAOENumber && WindowSettings.WarriorUseAOE && WindowSettings.WarriorUseInfuriate) || (Core.Player.CurrentHealthPercent < 40) && WindowSettings.WarriorUseInfuriate), r => Core.Player, r => 2, r => false)
            );
        }
        #endregion
        #region Combat
        public override Composite OnTreeSharpPulse()
        {
            return new PrioritySelector(
                new Decorator(r => WindowSettings.WarriorUseDefiance && !Core.Player.HasAura("Defiance"), Casting.Cast(r => "Defiance", r => true, r => Core.Player, r => 2, r => true))
                );
        }
        
        protected override Composite CreateCombat()
        {
            return new PrioritySelector(ctx => Core.Player.CurrentTarget,
                new Decorator(ctx => ctx != null,
                new PrioritySelector(

                new Decorator(r => BotManager.Current.IsAutonomous, new PrioritySelector(
                CommonBehaviors.MoveToLos(ctx => ctx as GameObject),
                CommonBehaviors.MoveAndStop(ctx => (ctx as GameObject).Location, ctx => 3 + (ctx as BattleCharacter).CombatReach, true, "[Magitek] Moving in Range"))),

                Combat.DoPVP(),

                #region AOE Mode
                new Decorator(r => WindowSettings.AOEEnabled && Core.Player.CurrentTarget.IsFlanking, new PrioritySelector(
                        Casting.Cast(r => "Infuriate", r => ((Extensions.EnemiesNearTarget(5) >= WindowSettings.WarriorUseAOENumber && WindowSettings.WarriorUseInfuriate) || (Core.Player.CurrentHealthPercent < 40) && WindowSettings.WarriorUseInfuriate), r => Core.Player, r => 3, r => false),
                        Casting.Cast(r => "Steel Cyclone", r => true, r => Core.Player, r => 2, r => false),
                        Casting.Cast(r => "Flash", r => WindowSettings.WarriorUseFlash && Core.Player.CurrentManaPercent >= WindowSettings.WarriorFlashStopMp, r => Core.Player, r => 2, r => false),
                        Casting.Cast(r => "Overpower", r => true, r => Core.Player.CurrentTarget, r => 2, r => false))),
                #endregion

                Casting.Cast(r => "Brutal Swing", r => (!WindowSettings.WarriorSaveBrutalSwing) || (WindowSettings.WarriorSaveBrutalSwing && Combat.CheckForInterrupt()), r => Core.Player.CurrentTarget, r => 2, r => false),
                Casting.Cast(r => "Provoke", r => WindowSettings.WarriorUseProvoke && Combat.ProvokeTarget() != null, r => Combat.ProvokeTarget(), r => 2, r => false),

                #region Toggle Mode
                new Decorator(ret =>
                {

                    if (!WindowSettings.WarriorDPSRotation && WindowSettings.WarriorToggleMode)
                        return true;

                    return false;

                }, new PrioritySelector(

                    BaseRotation,

                    Casting.Cast(r => "Butcher's Block", r => Actionmanager.LastSpell.Name == "Skull Sunder", r => Core.Player.CurrentTarget, r => 2, r => false),
                    Casting.Cast(r => "Skull Sunder", r => Actionmanager.LastSpell.Name == "Heavy Swing", r => Core.Player.CurrentTarget, r => 2, r => false),
                    Casting.Cast(r => "Heavy Swing", r => true, r => Core.Player.CurrentTarget, r => 2, r => false)
                    )),

                new Decorator(ret =>
                {

                    if (WindowSettings.WarriorDPSRotation && WindowSettings.WarriorToggleMode)
                        return true;

                    return false;

                }, new PrioritySelector(

                    BaseRotation,

                    Casting.Cast(r => "Storm's Eye", r => !Core.Player.CurrentTarget.HasAura("Storm's Eye", true, msLeft: 3000) && Actionmanager.LastSpell.Name == "Maim", r => Core.Player.CurrentTarget, r => 3, r => true),
                    Casting.Cast(r => "Storm's Path", r => !Core.Player.CurrentTarget.HasAura("Storm's Path", true, msLeft: 3000) && Actionmanager.LastSpell.Name == "Maim", r => Core.Player.CurrentTarget, r => 3, r => true),
                    Casting.Cast(r => "Maim", r => Actionmanager.LastSpell.Name == "Heavy Swing", r => Core.Player.CurrentTarget, r => 2, r => false),
                    Casting.Cast(r => "Heavy Swing", r => true, r => Core.Player.CurrentTarget, r => 2, r => false)
                    )),

                #endregion
                BaseRotation,
                #region Non-toggle Mode
                //Storm's Path and Storm's Eye if enabled.
                Casting.Cast(r => "Storm's Path", r => (Actionmanager.LastSpell.Name == "Maim" && !Core.Player.CurrentTarget.HasAura("Storm's Path")) || (Actionmanager.LastSpell.Name == "Maim" && !Core.Player.CurrentTarget.HasAura("Storm's Path", true, msLeft: 3000) && WindowSettings.WarriorStormPriority), r => Core.Player.CurrentTarget, r => 3, r => true),
                Casting.Cast(r => "Storm's Eye", r => (Actionmanager.LastSpell.Name == "Maim" && Core.Player.CurrentTarget.HasAura("Storm's Path") && WindowSettings.WarriorUseStormsEye || (Actionmanager.LastSpell.Name == "Maim" && !Core.Player.CurrentTarget.HasAura("Storm's Eye", true, msLeft: 3000) && WindowSettings.WarriorStormPriority && WindowSettings.WarriorUseStormsEye)), r => Core.Player.CurrentTarget, r => 3, r => true),

                //Maim if we have 2 Wrath and DOT/Debuff/Buff priority is enabled.
                Casting.Cast(r => "Maim", r => WindowSettings.WarriorStormPriority && (Core.Player.HasAura("Wrath II") || Core.Player.HasAura("Wrath III") || Core.Player.HasAura("Wrath IV") || Core.Player.HasAura("Infuriated")) &&
                    Actionmanager.LastSpell.Name == "Heavy Swing" && (!Core.Player.CurrentTarget.HasAura("Storm's Path", true, msLeft: 3000) || !Core.Player.CurrentTarget.HasAura("Storm's Eye", true, msLeft: 3000)), r => Core.Player.CurrentTarget, r => 3, r => false),

                //Maim if we have 4 Wrath, it means we've opened with 2 rotations of Butcher's Block.       
                Casting.Cast(r => "Maim", r => ((Actionmanager.LastSpell.Name == "Heavy Swing" && (Core.Player.HasAura("Wrath IV") || Core.Player.HasAura("Infuriated")) && !Core.Player.CurrentTarget.HasAura("Storm's Path") && WindowSettings.WarriorUseStormsPath) ||
                    (Actionmanager.LastSpell.Name == "Heavy Swing" && WindowSettings.WarriorUseStormsEye && Core.Player.CurrentTarget.HasAura("Storm's Path") && !Core.Player.CurrentTarget.HasAura("Storm's Eye")))
                    && Core.Player.CurrentTPPercent > 20
                    , r => Core.Player.CurrentTarget, r => 3, r => false),

                //Skull Sunder -> Butcher's Block if 
                Casting.Cast(r => "Butcher's Block", r => Actionmanager.LastSpell.Name == "Skull Sunder", r => Core.Player.CurrentTarget, r => 3, r => false),
                Casting.Cast(r => "Skull Sunder", r => Actionmanager.LastSpell.Name == "Heavy Swing", r => Core.Player.CurrentTarget, r => 3, r => false),
                //Start combo.
                Casting.Cast(r => "Heavy Swing", r => true, r => Core.Player.CurrentTarget, r => 3, r => false),

                //Tomahawk if out of melee range.
                Casting.Cast(r => "Tomahawk", r => WindowSettings.WarriorUseTomahawk && Core.Player.CurrentTarget.Location.Distance(Core.Player.Location) > 5, r => Core.Player.CurrentTarget, r => 3, r => false)
                #endregion

                )));
        }

        public Composite BaseRotation
        {
            get
            {
                return new PrioritySelector(

                    Casting.Cast(r => "Steel Cyclone", r => !WindowSettings._dontaoeList.Contains(Core.Player.CurrentTarget.Name) && Extensions.EnemiesNearTarget(5) >= WindowSettings.TargetsToAOE && Core.Player.HasAura("Infuriated"), r => Core.Player, r => 3, r => false),

                    Casting.Cast(r => "Flash", r => Core.Player.CurrentManaPercent >= WindowSettings.WarriorFlashStopMp && !WindowSettings._dontaoeList.Contains(Core.Player.CurrentTarget.Name) && WindowSettings.WarriorUseFlash && Extensions.EnemiesNearTarget(5) >= WindowSettings.TargetsToAOE, r => Core.Player, r => 3, r => false),
      
                    //Infuriate if enemies in AOE range.
                    Casting.Cast(r => "Infuriate", r => ((Extensions.EnemiesNearTarget(5) >= WindowSettings.WarriorUseAOENumber  && WindowSettings.WarriorUseInfuriate) || (Core.Player.CurrentHealthPercent < 40) && WindowSettings.WarriorUseInfuriate), r => Core.Player, r => 3, r => false),
                    //Manage Infuriated based on WindowSettings.
                    Casting.Cast(r => "Inner Beast", r => Core.Player.CurrentHealthPercent < 40 && Core.Player.HasAura("Infuriated") && WindowSettings.WarriorUseInnerBeast, r => Core.Player.CurrentTarget, r => 3, r => false),

                    //Spam Overpower for AOE, don't know a better way to handle it without being able to check Enmity.
                    Casting.Cast(r => "Overpower", r => WindowSettings.WarriorUseOverpower && Core.Player.CurrentTPPercent >= WindowSettings.WarriorOverpowerStopTp && Extensions.EnemiesNearTarget(5) >= WindowSettings.TargetsToAOE && !WindowSettings._dontaoeList.Contains(Core.Player.CurrentTarget.Name), r => Core.Player.CurrentTarget, r => 3, r => false),
          
                    Casting.Cast(r => "Inner Beast", r => Core.Player.HasAura("Infuriated") && WindowSettings.WarriorUseInnerBeast, r => Core.Player.CurrentTarget, r => 3, r => false),
                    Casting.Cast(r => "Provoke", r => WindowSettings.WarriorUseProvoke && Combat.ProvokeTarget() != null, r => Combat.ProvokeTarget(), r => 2, r => false),

                    //Mercy Stroke
                    Casting.Cast(r => "Mercy Stroke", r => true, r => Core.Player.CurrentTarget, r => 3, r => false),

                    //Haymaker if you have it and evaded.
                    Casting.Cast(r => "Haymaker", r => true, r => Core.Player.CurrentTarget, r => 2, r => false),

                    //Fracture if enabled.
                    Casting.Cast(r => "Fracture", r => Core.Player.HasAura("Wrath IV") && WindowSettings.WarriorUseFracture, r => Core.Player.CurrentTarget, r => 3, r => true));
            }
        #endregion  
        }
     }
  }